home *** CD-ROM | disk | FTP | other *** search
- rem $linesize:132
- rem $title:'Application Engineer Standard Routines'
- rem $subtitle:'Delete a key from the index - introduction'
- '
- ' Major modification(s)
- '
- ' 1) Reallocation of the key to the system.
- ' 2) Relinkage of the keys for the correct sequencing.
- '
- ' ==> still needed <==
- '
- ' 3) Balance checking of the keys during deletion.
- ' 4) Version to allocate 32 bit record pointers.
- '
- ' Modifications on 7th January, 1987.
- '
- ' More modifications on 10th January, 1987.
- '
- ' More modifications on 22nd January, 1987.
- '
- ' Taken out logical expressions. NOT and AND seem to behave in a
- ' different manner than expected. Use instead, math logical expressions.
- '
- ' Deleting keys with parents seems to be fine. The problem is deleting
- ' keys where their location is record 1 in the file. To do this correctly,
- ' a key needs to be moved from the left side of the index and placed in
- ' record 1. This key then needs to have it's childrens' parents' pointers
- ' reallocated, and then the previous position for this record placed on the
- ' deletion stack.
- '
- ' The above problem reared it's head on january 22nd. This time, when a key
- ' (which was in record 1) was deleted with only LEFT NODE children, the
- ' whole index would 'vanish' !
- '
- ' This is indeed a bug
- '
- ' This also happens to keys with RIGHT children ! Oh No !
- '
- ' (c) Copyright 1986, 1987 Roy Barrow
- '
- '
- ' Key = 1
- ' Left = 2
- ' Right = 3
- ' Parent = 4
- ' Master = 5
- ' Delete = 6
-
- rem $include:'AESHARED.BAS'
-
- sub bit.kill(fl%,ky$,mrec%,success%) static
-
- if mrec%<1 then
- goto badkey
- end if
-
- if success%<1 then
- goto badkey
- end if
-
- get #fl%,success% ' key to delete
-
- dk$=xk$(fl%,1%) ' key
- d.s%=success% ' position in file
- d.l%=cvi(xk$(fl%,2%)) ' left pointer
- d.r%=cvi(xk$(fl%,3%)) ' right pointer
- d.p%=cvi(xk$(fl%,4%)) ' parent pointer
- d.m%=cvi(xk$(fl%,5%)) ' pointer to ACTUAL record
- d.d%=cvi(xk$(fl%,6%)) ' pointer to next deleted
-
- if (d.p%<>0%) then ' there IS a parent
-
- rem $subtitle:'There is a parent and a left child'
- rem $page
- if (d.l%<>0%) and (d.r%=0%) then ' left ONLY
- get #fl%,d.p% ' get the parent
- if cvi(xk$(fl%,2%))=d.s% then ' yes, link to the left
- side%=2%
- else
- side%=3% ' otherwise, right
- end if
- lset xk$(fl%,side%)=mki$(d.l%) ' change the link
- put #fl%,d.p% ' write it back
- get #fl%,d.l% ' get the kid
- lset xk$(fl%,4%)=mki$(d.p%) ' relink the child
- put #fl%,d.l% ' write it back
- gosub init.key.rec ' init the record
- lset xk$(fl%,6%)=mki$(xh%(fl%,4%)) ' allocate on stack
- put #fl%,d.s% ' write it away
- xh%(fl%,4%)=d.s% ' new deleted lifo rec
- end if
- rem $subtitle:'There is a parent and a right child'
- rem $page
- if (d.r%<>0%) and (d.l%=0%) then ' right ONLY
- get #fl%,d.p% ' get the parent
- if cvi(xk$(fl%,2%))=d.s% then ' yes, link to the left
- side%=2%
- else
- side%=3% ' otherwise, right
- end if
- lset xk$(fl%,side%)=mki$(d.r%) ' change the link
- put #fl%,d.p% ' write it back
- get #fl%,d.r% ' get the kid
- lset xk$(fl%,4%)=mki$(d.p%) ' relink the child
- put #fl%,d.r% ' write it back
- gosub init.key.rec ' init the record
- lset xk$(fl%,6%)=mki$(xh%(fl%,4%)) ' allocate on stack
- put #fl%,d.s% ' write it away
- xh%(fl%,4%)=d.s% ' new deleted lifo rec
- end if
- rem $subtitle:'There is a parent , but no children'
- rem $page
- if ((d.l%=0%) and (d.r%=0%)) then ' NO children
- get #fl%,d.p% ' get the parent
- if cvi(xk$(fl%,2%))=d.s% then ' yes, link to the left
- side%=2%
- else
- side%=3% ' otherwise, right
- end if
- lset xk$(fl%,side%)=mki$(0%) ' change the link
- put #fl%,d.p% ' write it back
- gosub init.key.rec ' init the record
- lset xk$(fl%,6%)=mki$(xh%(fl%,4%)) ' allocate on stack
- put #fl%,d.s% ' write it away
- xh%(fl%,4%)=d.s% ' new deleted lifo rec
- end if
- rem $subtitle:'There is a parent and both left & right children'
- rem $page
- if (d.l%<>0%) and (d.r%<>0%) then ' Yup, two kids
- get #fl%,d.l% ' get the left
- lset xk$(fl%,4%)=mki$(d.p%) ' give a new parent
- put #fl%,d.l% ' write it back
- pnh%=d.l% ' last key so far
- nh%=cvi(xk$(fl%,3%)) ' right key
- while nh%<>0% ' keep getting
- get #fl%,nh% ' get right
- pnh%=nh% ' last key so far
- nh%=cvi(xk$(fl%,3%)) ' right key
- wend
- lset xk$(fl%,3%)=mki$(d.r%) ' link deleted's right to this
- put #fl%,pnh% ' write this one back
- get #fl%,d.r% ' get the right one
- lset xk$(fl%,4%)=mki$(pnh%) ' set the new parent
- put #fl%,d.r% ' write it back
- get #fl%,d.p% ' fetch the parent
- if cvi(xk$(fl%,2%))=d.s% then ' yes, link to the left
- side%=2%
- else
- side%=3% ' otherwise, right
- end if
- lset xk$(fl%,side%)=mki$(d.l%) ' change the link
- put #fl%,d.p% ' write it back
- gosub init.key.rec ' init the record
- lset xk$(fl%,6%)=mki$(xh%(fl%,4%)) ' allocate on stack
- put #fl%,d.s% ' write it away
- xh%(fl%,4%)=d.s% ' new deleted lifo rec
- end if
-
- elseif (d.s%=1%) then ' NO PARENT
- rem $subtitle:'No parent, and there is a left child'
- rem $page
- if (d.l%<>0%) and (d.r%=0%) then ' left ONLY
- get #fl%,d.l% ' get left
- lrec%=cvi(xk$(fl%,2%)) ' the left grandchild
- rrec%=cvi(xk$(fl%,3%)) ' the right grandchild
- lset xk$(fl%,4%)=mki$(0%) ' no parent for this
- put #fl%,1% ' write to 1
- if (lrec%<>0%) then ' yes, theres a left gc
- get #fl%,lrec% ' get the left grandchild
- lset xk$(fl%,4%)=mki$(1%) ' new parent
- put #fl%,lrec% ' put this record away
- end if
- if (rrec%<>0%) then ' yes, theres a right gc
- get #fl%,rrec% ' get the right grandchild
- lset xk$(fl%,4%)=mki$(1%) ' new parent
- put #fl%,rrec% ' put this record away
- end if
- gosub init.key.rec ' init the record
- lset xk$(fl%,6%)=mki$(xh%(fl%,4%)) ' allocate on stack
- put #fl%,d.l% ' write it away
- xh%(fl%,4%)=d.l% ' new deleted lifo rec
- end if
- rem $subtitle:'No parent, and there is a right child'
- rem $page
- if (d.r%<>0%) and (d.l%=0%) then ' right ONLY
- get #fl%,d.r% ' get right
- lrec%=cvi(xk$(fl%,2%)) ' the left grandchild
- rrec%=cvi(xk$(fl%,3%)) ' the right grandchild
- lset xk$(fl%,4%)=mki$(0%) ' no parent for this
- put #fl%,1% ' write to 1
- if (lrec%<>0%) then ' yes, theres a left gc
- get #fl%,lrec% ' get the left grandchild
- lset xk$(fl%,4%)=mki$(1%) ' new parent
- put #fl%,lrec% ' put this record away
- end if
- if (rrec%<>0%) then ' yes, theres a right gc
- get #fl%,rrec% ' get the right grandchild
- lset xk$(fl%,4%)=mki$(1%) ' new parent
- put #fl%,rrec% ' put this record away
- end if
-
- gosub init.key.rec ' init the record
- lset xk$(fl%,6%)=mki$(xh%(fl%,4%)) ' allocate on stack
- put #fl%,d.r% ' write it away
- xh%(fl%,4%)=d.r% ' new deleted lifo rec
- end if
- rem $subtitle:'No parent and no children'
- rem $page
- if ((d.l%=0%) and (d.r%=0%)) then ' NO children, NO parents, lonely!
- ' Just in case index is large ...
- close #fl% ' close the index
- hn$=idx.nam$(fl%) ' Name of the index
- kl%=xh%(fl%,1%) ' Key Length
-
- call Bit.Creatq(fl%,hn$,kl%) ' Re-create the file
- if aesb.fatal% then ' Fatal error opening index
- call ae.error("BITKIL/BITCRE(RE)")
- end if
- call Bit.Open(fl%,hn$) ' Ya got it, just create it again
- end if
- rem $subtitle:'No parent, but both left and right children'
- rem $page
- if (d.l%<>0%) and (d.r%<>0%) then ' Yup, two kids
- get #fl%,d.l% ' get the left
- lrec%=cvi(xk$(fl%,2%)) ' the left grandchild
- rrec%=cvi(xk$(fl%,3%)) ' the right grandchild
- lset xk$(fl%,4%)=mki$(0%) ' no parent for this
- put #fl%,1% ' write to 1
- if (lrec%<>0%) then ' yes, theres a left gc
- get #fl%,lrec% ' get the left grandchild
- lset xk$(fl%,4%)=mki$(1%) ' new parent
- put #fl%,lrec% ' put this record away
- end if
- if (rrec%<>0%) then ' yes, theres a right gc
- get #fl%,rrec% ' get the right grandchild
- lset xk$(fl%,4%)=mki$(1%) ' new parent
- put #fl%,rrec% ' put this record away
- end if
- get #fl%,1% ' get left again
- ' thats where the new record is now
- pnh%=1% ' last key so far
- nh%=cvi(xk$(fl%,3%)) ' right key
- while nh%<>0% ' keep getting
- get #fl%,nh% ' get right
- pnh%=nh% ' last key so far
- nh%=cvi(xk$(fl%,3%)) ' right key
- wend
- lset xk$(fl%,3%)=mki$(d.r%) ' link deleted's right to this
- put #fl%,pnh% ' write this one back
- get #fl%,d.r% ' get the right one
- lset xk$(fl%,4%)=mki$(pnh%) ' set the new parent
- put #fl%,d.r% ' write it back
- gosub init.key.rec ' init the record
- lset xk$(fl%,6%)=mki$(xh%(fl%,4%)) ' allocate on stack
- put #fl%,d.l% ' write it away
- xh%(fl%,4%)=d.l% ' new deleted lifo rec
- end if
-
- end if
-
- goto goodkey
- rem $subtitle:'Initialize a key to blanks'
- rem $page
- init.key.rec: ' Initialize the key
- for j%=2% to 6%
- lset xk$(fl%,j%)=mki$(0%)
- next j%
- lset xk$(fl%,1%)=string$(xh%(fl%,1%)+10%,0%)
- xh%(fl%,2)=xh%(fl%,2)-1
- return
-
- goodkey:
- success%=1
- goto deleted
- badkey:
- mrec%=0
- success%=0
- deleted:
- end sub
-
-